# 关于评论的序列化器

from rest_framework import serializers
from sa.models import *


class CommentSerializer(serializers.ModelSerializer):
    """
    评论序列化器
    article和 author 是不变的恒定值，就是当前文章和当前用户
    直接在视图的save()方法中增加处理，直接在fields里排除， 不用显示指定。
    如果是：多种可能的变筻值，例如 author 如果可选，
    那么就应该在序列化器里显示指定，并通过前端显式提交。
    """
    # 反序列化输入，传入id （write_only）
    # article = serializers.PrimaryKeyRelatedField(
    #     queryset=Article.objects.all(), write_only=True,
    #     help_text="对应文章ID,仅反序列化！"
    # )
    parent = serializers.PrimaryKeyRelatedField(
        queryset=Comment.objects.all(),
        write_only=True,
        required=False,
        allow_null=True,
        help_text="父评论ID（可选）,仅反序列化！"
    )
    # 序列化输出 （read_only）
    article_obj = serializers.SerializerMethodField(
        read_only=True, help_text='评论所属文章'
    )
    # author属性在 self.context 或视图去处理
    author_obj = serializers.SerializerMethodField(
        read_only=True, help_text='评论者属性'
    )
    created_at = serializers.SerializerMethodField()
    parent_obj = serializers.SerializerMethodField(
        read_only=True, help_text='父评论摘要',
        required=False  # 因为可能是第一级评论
    )
    # 增加视图views中嵌套的回复评论字段，树状结构
    replies = serializers.SerializerMethodField(
        read_only=True, help_text='回复评论'
    )

    class Meta:
        model = Comment
        # 不包含 , author, 'article', 在视图中处理
        fields = ['id', 'parent', 'content', 'article_obj', 'author_obj',
                  'created_at', 'parent_obj', 'depth', 'replies']
        read_only_fields = ['id', 'depth', 'replies']  # depth也在视图中自动生成

    # obj 参数指的是 当前正在被序列化的模型实例（即 Comment 对象）
    def get_article_obj(self, obj):
        return {
            'id': obj.article.id,
            'title': obj.article.title
        }

    def get_author_obj(self, obj):
        return {
            'id': obj.author.id,
            'cn_name': obj.author.cn_name,
        }

    def get_created_at(self, obj):
        return obj.created_at.strftime("%Y-%m-%d %H:%M:%S")

    def get_parent_obj(self, obj):
        if not obj.parent:
            return None
        return {
            'id': obj.parent.id,
            'author': obj.parent.author.cn_name,
            'content': obj.parent.content
        }

    def get_replies(self, obj):
        if hasattr(obj, 'replies'):
            # 使用当前序列化器序列化子评论
            # 与 视图views 中 self.get_serializer(instance=实例, many=True)
            return CommentSerializer(instance=obj.replies, many=True).data
        return []


    def validate(self, attrs):  # 考虑下，是否应该在视图来处理这些数据
        # author 字段直接使用当前登录用户
        # request = self.context.get('request')
        # if request and hasattr(request, 'user'):
        #     attrs['author'] = request.user
        # else:
        #     raise serializers.ValidationError('Authentication required')

        # depth 从父评论的depth字段+1
        # parent_comment = attrs.get('parent')    # 是一个对象
        # if parent_comment:
        #     attrs['depth'] = parent_comment.depth + 1
        # else:
        #     attrs['depth'] = 0  # 没有父评论，深度为0

        return attrs
